package com.uw.uwrpc.core.util;


import com.uw.uwrpc.core.exception.RpcException;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class MethodUtil {
    private MethodUtil() {
    }

    private final static Set<String> objectMethod = new HashSet<>();

    static {
        objectMethod.add("toString");
        objectMethod.add("hashCode");
        objectMethod.add("notifyAll");
        objectMethod.add("equals");
        objectMethod.add("wait");
        objectMethod.add("getClass");
        objectMethod.add("notify");
    }

    // 原始类型到其包装类型的映射
    private static final Map<String, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE = new HashMap<>();

    static {
        PRIMITIVE_TO_WRAPPER_TYPE.put("boolean", Boolean.class);
        PRIMITIVE_TO_WRAPPER_TYPE.put("byte", Byte.class);
        PRIMITIVE_TO_WRAPPER_TYPE.put("char", Character.class);
        PRIMITIVE_TO_WRAPPER_TYPE.put("double", Double.class);
        PRIMITIVE_TO_WRAPPER_TYPE.put("float", Float.class);
        PRIMITIVE_TO_WRAPPER_TYPE.put("int", Integer.class);
        PRIMITIVE_TO_WRAPPER_TYPE.put("long", Long.class);
        PRIMITIVE_TO_WRAPPER_TYPE.put("short", Short.class);
        PRIMITIVE_TO_WRAPPER_TYPE.put("void", Void.class); // void类型也作为特殊情况处理
    }


    // TODO: 重载实现过滤
    public static boolean checkObjectMethod(final String method) {
        return objectMethod.contains(method);
    }


    public static boolean checkObjectMethod(final Method method) {
        return Object.class.equals(method.getDeclaringClass());
    }

    public static String getMethodSign(final Method method) {
        //String className = method.getDeclaringClass().getCanonicalName();
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        String parameterTypesStr = Arrays.stream(parameterTypes)
                .map(Class::getName)
                .collect(Collectors.joining(","));

        //return className + "#" + methodName + "(" + parameterTypesStr + ")";
        return methodName + "(" + parameterTypesStr + ")";
    }

    public static List<Class<?>> getParameterClass(final String methodSignature) {
        List<Class<?>> result = new ArrayList<>();

        String parameterPart = methodSignature.substring(methodSignature.indexOf('(') + 1, methodSignature.indexOf(')'));

        // 分割参数类型字符串以获取每个参数类型
        String[] parameterTypeNames = parameterPart.split(",");

        try {
            // 遍历参数类型字符串数组，并获取每个参数的Class对象
            for (String typeName : parameterTypeNames) {
                if (StringUtils.hasText(typeName)) {
                    typeName = typeName.trim(); // 去除可能存在的空白字符
                    Class<?> parameterType = null;

                    parameterType = getClassFromTypeName(typeName);
                    result.add(parameterType);

                }
            }
        } catch (ClassNotFoundException e) {
            throw new RpcException(e);
        }
        return result;
    }

    private static Class<?> getClassFromTypeName(String typeName) throws ClassNotFoundException {
        // 检查是否是原始类型
        if (PRIMITIVE_TO_WRAPPER_TYPE.containsKey(typeName)) {
            return PRIMITIVE_TO_WRAPPER_TYPE.get(typeName);
        } else {
            // 对于非原始类型，使用Class.forName加载
            return Class.forName(typeName);
        }
    }
}
